%%%----------------------------------------------------------------------
%%% File    : http_scan.xrl
%%% Author  : Stuart Jackson <sjackson@simpleenigma.com> [http://www.simpleenigma.com]
%%% Purpose : HTTP request and response token scanner
%%% Created : 2007-01-17
%%% Updated : 2007-01-17
%%%----------------------------------------------------------------------

Definitions.
OCTET    = [.]
CHAR     = [\000-\d]
UPALPHA  = [A-Z]
LOALPHA  = [a-z]
ALPHA    = ({UPALPHA}|{LOALPHA})
DIGIT    = [0-9]
HEX      = [0-9a-fA-F]
ALPHANUM = ({ALPHA}|{DIGIT})
CR       = [\r]
LF       = [\n]
SP       = [\s]
HT       = [\t]
DQ       = [\034]
CRLF     = [\r\n]
LWS      = ({CRLF}|{SP}|{HT})
TEXT     = [^\000-\008\011\012\014-\031\127]
CTL      = [\000-\031\d]
SEP      = [()<>@,;:\\\"\/\[\]?={}]
TOK      = [^{SEP}{CTL}]
HTTP     = ([Hh][Tt][Tt][Pp])
RESERVED = [;\/?:@&=+$,]
MARK     = [-_.!~*'()]
UNRESRVD = ({ALPHANUM}|{MARK})
DELIMES  = [<>#%\034]
UNWISE   = [{}\|\\\^\[\]\`]
CONTENT  = "(.)*"
NUM     = {DIGIT}+
VER     = {HTTP}\/{NUM}\.{NUM}
END     = [\000]
HEADER  = {UNRESRVD}+:{LWS}+

Rules.

{VER} : {token,{version,TokenChars}}.
{NUM} : {token,{integer,list_to_integer(TokenChars)}}.

{HTTP} : {token,{scheme,TokenChars}}.

{HEADER} : 
	[H,_Rest] = string:tokens(TokenChars,[58]),
	{token,{header,H}}.

({UNRESRVD}+([,;])*) : {token,{string,TokenChars}}.
({UNRESRVD}+/{UNRESRVD}+([,;])*) : {token,{string,TokenChars}}.
({ALPHA}+/{NUM}.{NUM}) : {token,{string,TokenChars}}.
{RESERVED}  : {token,{list_to_atom(TokenChars)}}.
{CONTENT}   : {token,{body,lists:sublist(TokenChars, 2, TokenLen - 2)}}.

{SP} : skip_token.
{LWS}+   : skip_token.


Erlang code.
-export([http_string/1]).

http_string(String) ->
	RegExp = "([Cc][Oo][Nn][Tt][Ee][Nn][Tt])-([Ll][Ee][Nn][Gg][Tt][Hh]):([\s])+([0-9])+",
	case regexp:match(String,RegExp) of
		nomatch -> 
			{ok,S,Lines} = string(String),
			{ok,lists:append([S,[{'$end'}]]),Lines};
		{match,Start,Len} ->
			ContentLength = string:substr(String,Start,Len),
			List = string:tokens(ContentLength,"\s\t"),
			LString = lists:last(List),
			Length = list_to_integer(LString),
			{Begin,End} = lists:split(length(String)-Length-2,String),
			{Content,Rest} = lists:split(Length,End),
			NewString = lists:append([Begin,[34],Content,[34],Rest]),
			{ok,S,Lines} = string(NewString),
			{ok,lists:append([S,[{'$end'}]]),Lines}
	end.
